<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <style>
        body{
            outline: lightblue solid;
        }
        output{
            padding: 1rem;
            font-size: 2rem;
            background: skyblue;
        }
    </style>
</head>
<body>
<div id="container">
    <output>0</output>
</div>
<script src="underscore-1.9.1.js"></script>
<script>
    onload = function () {
        let counter = 0;
        let output = document.querySelector('output');
        // document.querySelector('body').addEventListener('onmousemove',_.debounce(function () {
        document.querySelector('body').onmousemove = _.myThrottle(function () {
            output.innerText = counter+++'';
        },1500)
    };
    // underscore源码
    _.myThrottle = function(func, wait, options) {
        var timeout, context, args, result;
        var previous = 0;
        if (!options) options = {};

        var later = function() {
            previous = options.leading === false ? 0 : _.now();
            timeout = null;
            result = func.apply(context, args);
            if (!timeout) context = args = null;
        };

        var throttled = function() {
            var now = _.now();
            if (!previous && options.leading === false) previous = now;
            var remaining = wait - (now - previous);
            context = this;
            args = arguments;
            // 正常情况下remaining > wait不会发生，除非now比previous还要早(比如系统时间被修改)
            if (remaining <= 0 || remaining > wait) { // 每个首次触发的执行
                if (timeout) {
                    clearTimeout(timeout);
                    timeout = null;
                }
                previous = now;
                result = func.apply(context, args);
                if (!timeout) context = args = null;
            } else if (!timeout && options.trailing !== false) { // 每个第二次触发，埋下定时器，此后到定时器结束之前不会再响应事件
                timeout = setTimeout(later, remaining);
            }
            return result;
        };


        throttled.cancel = function() {
            clearTimeout(timeout);
            previous = 0;
            timeout = context = args = null;
        };

        return throttled;
    };
</script>
</body>
</html>